
import sys
from PyQt5.QtWidgets import QWidget,QApplication,QMessageBox
import form
import sys
from PyQt5.QtCore import QThread, pyqtSignal, QObject, QTimer, QDateTime
import time
import threading
from UDP import UDP_Qthread_function
from TCP_Client import TCP_Client_Qthread_function
from TCP_Server import TCP_Server_Qthread_function
from PyQt5.QtNetwork import QNetworkInterface
from PyQt5.QtGui import QTextCursor, QColor

class initForm(QWidget):
    def __init__(self):
        super().__init__()
        self.ui = form.Ui_Form()
        self.ui.setupUi(self)
        self.setWindowTitle("网络调试助手")
        self.UI_Init()
        self.UDP_Init()
        self.TCP_Client_Init()
        self.TCP_Server_Init()
        print("主线程id:", threading.current_thread().ident)
        self.receiveLength = 0
        self.sendLength = 0
        
    def UDP_Init(self):
        self.UDP_QThread = QThread()
        self.UDP_QThread_function = UDP_Qthread_function()
        self.UDP_QThread_function.moveToThread(self.UDP_QThread)
        self.UDP_QThread.start()
        self.UDP_QThread_function.signal_UDP_qthread_function_Init.connect(self.UDP_QThread_function.UDP_qthread_function_Init)
        self.UDP_QThread_function.signal_pushButton_Open.connect(self.UDP_QThread_function.slot_pushButton_Open)
        self.UDP_QThread_function.signal_send_data.connect(self.UDP_QThread_function.slot_send_data)
        self.UDP_QThread_function.signal_send_data_num.connect(self.slot_send_data_num)
        self.UDP_QThread_function.signal_pushButton_Open_flag.connect(self.pushButton_Open_flag)
        self.UDP_QThread_function.signal_readyRead.connect(self.solt_readyRead)
        self.UDP_QThread_function.signal_UDP_qthread_function_Init.emit()
        
    def TCP_Client_Init(self):
        self.TCP_Client_QThread = QThread()
        self.TCP_Client_QThread_function = TCP_Client_Qthread_function()
        self.TCP_Client_QThread_function.moveToThread(self.TCP_Client_QThread)
        self.TCP_Client_QThread.start()
        self.TCP_Client_QThread_function.signal_TCP_Client_qthread_function_Init.connect(self.TCP_Client_QThread_function.TCP_Client_qthread_function_Init)
        self.TCP_Client_QThread_function.signal_pushButton_Open.connect(self.TCP_Client_QThread_function.slot_pushButton_Open)
        self.TCP_Client_QThread_function.signal_send_data.connect(self.TCP_Client_QThread_function.slot_send_data)
        self.TCP_Client_QThread_function.signal_send_data_num.connect(self.slot_send_data_num)
        self.TCP_Client_QThread_function.signal_pushButton_Open_flag.connect(self.pushButton_Open_flag)
        self.TCP_Client_QThread_function.signal_readyRead.connect(self.solt_readyRead)
        self.TCP_Client_QThread_function.signal_TCP_Client_qthread_function_Init.emit()
        
    def TCP_Server_Init(self):
        self.TCP_Server_QThread = QThread()
        self.TCP_Server_QThread_function = TCP_Server_Qthread_function()
        self.TCP_Server_QThread_function.moveToThread(self.TCP_Server_QThread)
        self.TCP_Server_QThread.start()
        self.TCP_Server_QThread_function.signal_TCP_Server_qthread_function_Init.connect(self.TCP_Server_QThread_function.TCP_Server_qthread_function_Init)
        self.TCP_Server_QThread_function.signal_pushButton_Open.connect(self.TCP_Server_QThread_function.slot_pushButton_Open)
        self.TCP_Server_QThread_function.signal_send_data.connect(self.TCP_Server_QThread_function.slot_send_data)
        self.TCP_Server_QThread_function.signal_closeClient.connect(self.TCP_Server_QThread_function.slot_closeClient)
        self.TCP_Server_QThread_function.signal_send_data_num.connect(self.slot_send_data_num)
        self.TCP_Server_QThread_function.signal_pushButton_Open_flag.connect(self.pushButton_Open_flag)
        self.TCP_Server_QThread_function.signal_readyRead.connect(self.solt_readyRead)
        self.TCP_Server_QThread_function.signal_NewClient.connect(self.slot_NewClient)
        self.TCP_Server_QThread_function.signal_TCP_Server_qthread_function_Init.emit()

    def UI_Init(self):
        comboBox_ProtocolType = {'UDP', 'TCP Client', 'TCP Server'}
        self.ui.comboBox_ProtocolType.currentTextChanged.connect(self.ComboBox_ProtocolType)
        self.ui.comboBox_ProtocolType.addItems(comboBox_ProtocolType)
        self.ui.lineEdit_HostPort.clear()
        self.ui.lineEdit_HostPort.setText("8888")
        self.ui.pushButton_Open.clicked.connect(self.pushButton_Open)
        self.ui.pushButton_Send.clicked.connect(self.pushButton_Send)
        self.ui.pushButton_Disconnect.clicked.connect(self.pushButton_Disconnect)
        
        self.time_send = QTimer()
        self.time_send.timeout.connect(self.timeOut_Send)
        self.ui.checkBox_TimeSend.stateChanged.connect(self.checkBox_TimeSend)
        self.ui.checkBox_HexDisplay.stateChanged.connect(self.checkBox_HexDisplay)
        self.ui.lineEdit_IntervalTime.setText("500")
        self.ui.pushButton_CleanReceive.clicked.connect(self.pushButton_CleanReceive)
        self.ui.pushButton_CleanSend.clicked.connect(self.pushButton_CleanSend)

    def slot_NewClient(self,parameter):
        print("NewClient", parameter)
        self.ui.comboBox_ClientIp.clear()
        self.ui.comboBox_ClientIp.addItems(parameter)
    
    def solt_readyRead(self,data):
        self.receiveLength = self.receiveLength + len(data['buf']) 
        self.ui.label_Receive.setText("接收： " + str(self.receiveLength))
        
        if self.ui.checkBox_TimeStamp.checkState():
            # time_str = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) + "  "
            currentDateTime = QDateTime.currentDateTime()
            time_str = currentDateTime.toString("yyyy-MM-dd hh:mm:ss.zzz") + "  "
            self.ui.textEdit_DataReceive.setTextColor(QColor(255, 100, 100))
            self.ui.textEdit_DataReceive.insertPlainText(time_str)
            self.ui.textEdit_DataReceive.setTextColor(QColor(0,0,0))
        
        view_data = ''
        Byte_data = bytes(data['buf'])
        if self.ui.checkBox_HexReceive.checkState():
            for i in range(0, len(Byte_data)):
                view_data = view_data + '{:02x}'.format(Byte_data[i]) + ' '
        else:
            view_data = Byte_data.decode('utf_8', 'ignore')
            
        choose_type = self.ui.comboBox_ProtocolType.currentText()
        if choose_type == 'UDP':
            # print("UDP收到数据", data['ip'], data['port'], data['buf'])
            self.ui.textEdit_DataReceive.setTextColor(QColor(255, 100, 100))
            self.ui.textEdit_DataReceive.insertPlainText("[" + data['ip'] + ": " + str(data['port']) + "]" + "\r\n")
            self.ui.textEdit_DataReceive.setTextColor(QColor(0,0,0))
        elif choose_type == 'TCP Server':
            # print("TCP Server收到数据", data['ip'], data['port'], data['buf'])
            self.ui.textEdit_DataReceive.setTextColor(QColor(255, 100, 100))
            self.ui.textEdit_DataReceive.insertPlainText("[" + data['ip'] + ": " + str(data['port']) + "]" + "\r\n")
            self.ui.textEdit_DataReceive.setTextColor(QColor(0,0,0))
        else:
            print("TCP Client收到数据", data['ip'], data['port'], data['buf'])
            
        self.ui.textEdit_DataReceive.insertPlainText(view_data + "\r\n")
        self.ui.textEdit_DataReceive.moveCursor(QTextCursor.End)  
    
    def pushButton_Open(self):
        print("点击打开按钮")
        chosse_type = self.ui.comboBox_ProtocolType.currentText()
        parameter = {}
        parameter['ip'] = self.ui.comboBox_HostIp.currentText()
        parameter['port'] = self.ui.lineEdit_HostPort.text()
        
        if chosse_type == "UDP":
            self.UDP_QThread_function.signal_pushButton_Open.emit(parameter)
        elif chosse_type == 'TCP Server':
            self.TCP_Server_QThread_function.signal_pushButton_Open.emit(parameter)
        else:
            self.TCP_Client_QThread_function.signal_pushButton_Open.emit(parameter)

    def pushButton_Disconnect(self):
        print("断开客户端")
        parameter = self.ui.comboBox_ClientIp.currentText()
        self.TCP_Server_QThread_function.signal_closeClient.emit(parameter)

    def pushButton_Send(self):
        send_buf = ''
        if self.ui.checkBox_HexDisplay.checkState():
            send_list = []
            send_text = self.ui.textEdit_Send.toPlainText()
            while send_text != '':
                try:
                    num = int(send_text[0:2],16)
                except:
                    QMessageBox.warning(self, '错误信息', '请正确输入16进制数据')
                    return
                send_text = send_text[2:].strip()
                send_list.append(num)
            input_s = bytes(send_list).decode()
            if self.ui.checkBox_SendEnd.checkState():
                send_buf = input_s + '\r\n'
            else:
                send_buf = input_s
        else:
            if self.ui.checkBox_SendEnd.checkState():
                send_buf = self.ui.textEdit_Send.toPlainText() + '\r\n'
            else:
                send_buf = self.ui.textEdit_Send.toPlainText()
        Byte_data = str.encode(send_buf)
        print("发送数据: ", Byte_data)
        
        choose_type = self.ui.comboBox_ProtocolType.currentText()
        parameter = {}
        parameter['ip_port'] = self.ui.comboBox_ClientIp.currentText()
        parameter['data']    = Byte_data
        
        if choose_type == 'UDP':
            self.UDP_QThread_function.signal_send_data.emit(parameter)
        elif choose_type == 'TCP Server':
            self.TCP_Server_QThread_function.signal_send_data.emit(parameter)
        else:
            self.TCP_Client_QThread_function.signal_send_data.emit(parameter)
        
    def timeOut_Send(self):
        self.pushButton_Send()
    
    def checkBox_TimeSend(self,state):
        print("勾选定时器")
        if state == 2:
            time_data = self.ui.lineEdit_IntervalTime.text()
            self.time_send.start(int(time_data))
        else:
            self.time_send.stop()

    def pushButton_CleanReceive(self):
        print("清除接收")
        self.receiveLength = 0
        self.ui.label_Receive.setText("接收: " + str(self.receiveLength))
        self.ui.textEdit_DataReceive.clear()
        
    def pushButton_CleanSend(self):
        print("清除发送")
        self.sendLength = 0
        self.ui.label_Send.setText("接收: " + str(self.sendLength))
        self.ui.textEdit_Send.clear()

    def checkBox_HexDisplay(self, state):
        print("16进制发送", state)
        if state == 2:
            send_text = self.ui.textEdit_Send.toPlainText()
            Byte_text = str.encode(send_text)
            view_data = ''
            for i in range(0, len(Byte_text)):
                view_data = view_data + '{:02x}'.format(Byte_text[i]) + ' '
                self.ui.textEdit_Send.setText(view_data)
        else:
            send_list = []
            send_text = self.ui.textEdit_Send.toPlainText()
            while send_text != '':
                try:
                    num = int(send_text[0:2], 16)
                except:
                    QMessageBox.warning(self, '错误信息', '请正确输入16进制数据')
                    return
                send_text = send_text[2:].strip()
                send_list.append(num)
            input_s = bytes(send_list)
            self.ui.textEdit_Send.setText(input_s.decode())

    def slot_send_data_num(self, num):
        self.sendLength = self.sendLength + num
        self.ui.label_Send.setText("发送: " + str(self.sendLength))

    def pushButton_Open_flag(self, state):
        print("打开状态", state)
        if state == 0:
            #端口被占用，弹窗报错
            QMessageBox.warning(self, '警告','打开失败,检查是否被占用')
        elif state == 1:
            #已经打开成功
            self.ui.pushButton_Open.setText("关闭")
            self.ui.pushButton_Open.setStyleSheet("color:red")
            self.ui.comboBox_HostIp.setEnabled(False)
            self.ui.comboBox_ProtocolType.setEnabled(False)
            self.ui.lineEdit_HostPort.setEnabled(False)
        else:
            #已经关闭
            self.ui.pushButton_Open.setText("打开")
            self.ui.pushButton_Open.setStyleSheet("color:black")
            self.ui.comboBox_HostIp.setEnabled(True)
            self.ui.comboBox_ProtocolType.setEnabled(True)
            self.ui.lineEdit_HostPort.setEnabled(True)
    
    def ComboBox_ProtocolType(self, str):
        scan_ip = self.Search_ip()
        self.ui.comboBox_HostIp.clear()
        self.ui.comboBox_HostIp.addItems(scan_ip)
        if str == 'UDP':
            print("选中UDP")
            self.ui.label_hostip.setText("本地主机地址")
            self.ui.label_hostport.setText("本地主机端口")
            self.ui.comboBox_HostIp.setEditable(False)
            self.show_client_window()
            self.ui.comboBox_ClientIp.setEditable(True)
            self.ui.label_Client.setText("远程主机")
            self.ui.pushButton_Disconnect.hide()
        elif str == 'TCP Client':
            print("选中TCP Client")
            self.ui.label_hostip.setText("远程主机地址")
            self.ui.label_hostport.setText("远程主机端口")
            self.ui.comboBox_HostIp.setEditable(True)
            self.hide_client_window()
            self.ui.comboBox_ClientIp.setEditable(True)
            self.ui.label_Client.setText("远程服务器")
        else:
            print("选中TCP Server")
            self.ui.label_hostip.setText("本地主机地址")
            self.ui.label_hostport.setText("本地主机端口")
            self.ui.comboBox_HostIp.setEditable(False)
            self.show_client_window()
            self.ui.comboBox_ClientIp.setEditable(False)
            self.ui.label_Client.setText("远程客户端")

    def show_client_window(self):
        self.ui.label_Client.show()
        self.ui.comboBox_ClientIp.show()
        self.ui.pushButton_Disconnect.show()

    def hide_client_window(self):
        self.ui.label_Client.hide()
        self.ui.comboBox_ClientIp.hide()
        self.ui.pushButton_Disconnect.hide()
    
    def Search_ip(self):
        list_ip = QNetworkInterface.allAddresses()
        scan_ip = []
        for ip in list_ip:
            if ip.isNull():
                continue
            nprotocol = ip.protocol()
            if nprotocol == 0:
                scan_ip.append(ip.toString())
                
        return scan_ip
 
    def closeEvent(self, event):
        print("窗体关闭")
        self.UDP_QThread.quit()
        self.UDP_QThread.wait()
        del self.UDP_QThread_function

        self.TCP_Client_QThread.quit()
        self.TCP_Client_QThread.wait()
        del self.TCP_Client_QThread_function

        self.TCP_Server_QThread.quit()
        self.TCP_Server_QThread.wait()
        del self.TCP_Server_QThread_function
        
        
if __name__ == "__main__":
    app = QApplication(sys.argv)
    wl = initForm()
    wl.show()
    sys.exit(app.exec())